"""简易用户认证路由."""

from datetime import datetime
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Request, status
from pydantic import BaseModel, Field
from loguru import logger

from backend.common.config import config_manager
from backend.database.db import db_manager
from backend.deps.auth import get_current_user
from backend.utils.auth import create_access_token, hash_password, verify_password


router = APIRouter(
    prefix=f"/{config_manager.api.version}/auth",
    tags=["auth"],
)


class UserPublic(BaseModel):
    id: str
    username: str
    nickname: Optional[str] = None
    created_at: Optional[datetime] = None


class RegisterRequest(BaseModel):
    username: str = Field(min_length=3, max_length=64)
    password: str = Field(min_length=6, max_length=128)
    nickname: Optional[str] = Field(default=None, max_length=64)


class LoginRequest(BaseModel):
    username: str = Field(min_length=3, max_length=64)
    password: str = Field(min_length=6, max_length=128)


class TokenResponse(BaseModel):
    token: str
    user: UserPublic


class AuthConfigResponse(BaseModel):
    auth_required: bool
    allow_register: bool
    anonymous_user_id: str = "anonymous"


def _row_to_user(row) -> Optional[UserPublic]:
    if not row:
        return None
    if isinstance(row, dict):
        return UserPublic(
            id=row.get("id"),
            username=row.get("username"),
            nickname=row.get("nickname"),
            created_at=row.get("created_at"),
        )
    return UserPublic(
        id=row[0],
        username=row[1],
        nickname=row[3] if len(row) > 3 else None,
        created_at=row[4] if len(row) > 4 else None,
    )


def _build_token_response(user_row) -> TokenResponse:
    user = _row_to_user(user_row)
    payload = {"sub": user.id, "username": user.username}
    token = create_access_token(payload, expires_minutes=config_manager.auth.jwt_expire_minutes)
    return TokenResponse(token=token, user=user)


@router.get("/config", response_model=AuthConfigResponse, summary="获取认证特性配置")
async def get_auth_config() -> AuthConfigResponse:
    """公开认证开关，便于前端确定是否强制登录。"""
    feature_auth = bool(config_manager.auth.feature_auth)
    return AuthConfigResponse(
        auth_required=feature_auth,
        allow_register=bool(config_manager.auth.allow_register),
        anonymous_user_id="anonymous",
    )


@router.post("/register", response_model=UserPublic)
async def register(payload: RegisterRequest):
    if not config_manager.auth.feature_auth:
        raise HTTPException(status_code=400, detail="Auth feature disabled")
    if not config_manager.auth.allow_register:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Registration disabled")

    existing = db_manager.get_user_by_username(payload.username)
    if existing:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Username already exists")

    try:
        # Hash the password with proper error handling
        password_hash = hash_password(payload.password)
        user = db_manager.create_user(
            username=payload.username,
            password_hash=password_hash,
            nickname=payload.nickname,
        )
        return _row_to_user(user)
    except ValueError as e:
        logger.error(f"Password hashing error: {str(e)}")
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid password: {str(e)}")


@router.post("/login", response_model=TokenResponse)
async def login(payload: LoginRequest):
    if not config_manager.auth.feature_auth:
        raise HTTPException(status_code=400, detail="Auth feature disabled")

    user_row = db_manager.get_user_by_username(payload.username.strip())
    if not user_row:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid credentials")

    stored_hash = user_row["password_hash"] if isinstance(user_row, dict) else user_row[2]
    if not verify_password(payload.password, stored_hash):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid credentials")

    return _build_token_response(user_row)


@router.post("/logout")
async def logout(_: Request, current_user: dict = Depends(get_current_user)):
    logger.info(f"User {current_user.get('id')} logged out")
    return {"success": True}
